﻿using System;

namespace RabbitMQExtension
{
    /// <summary>
    /// 消费者客户端接口
    /// </summary>
    public interface IMQConsumerClient : IDisposable
    {
        ILog Log { get; set; }

        /// <summary>
        /// 设置连接信息
        /// </summary>
        /// <param name="config">连接信息</param>
        void SetConnectInfo(MQConfig config);

        /// <summary>
        /// 与服务器是否处于连接状态。
        /// </summary>
        /// <returns>true:已连接，false:未连接。</returns>
        bool IsConnected();

        /// <summary>
        /// 开始接收指定消息队列的消息。。
        /// </summary>
        /// <param name="queue">要消费的消息队列的名称。</param>
        /// <param name="mpc">消息处理回调函数。</param>
        void StartConsumer(string queue, MessageProcessCallback mpc);

        /// <summary>
        /// 开始接收topic方式推送的消息。
        /// </summary>
        /// <param name="topices">要消费的消息队列标志，可以多个,多个之间以"||"分隔</param>
        /// <param name="filterKeys">对消费的消息队列进行二次过滤，与<paramref name="topices"/>一一对应，以"||"分隔，如果要单个队列使用多个过滤条件，过滤条件之间使用","分隔。
        /// 都不过滤使用"*"或传空字符。</param>
        /// <param name="mpc">消息处理回调函数，把你处理消息的函数传进来。</param>
        void StartTopicConsumer(string topices, string filterKey, MessageProcessCallback mpc);

        /// <summary>
        /// 开始接收发布订阅方式推送的消息。
        /// </summary>
        /// <param name="topices">要消费的消息队列标志，可以多个,多个之间以"||"分隔</param>
        /// <param name="mpc">消息处理回调函数，把你处理消息的函数传进来。</param>
        void StartPubSubConsumer(string topices, MessageProcessCallback mpc);

        /// <summary>
        /// 从队列中拉取一条消息
        /// </summary>
        /// <param name="queue">队列名</param>
        /// <param name="mpc">回调函数</param>
        void Pull(string queue, MessageProcessCallback mpc);

        /// <summary>
        /// 关闭所有连接，停止接收消息。
        /// </summary>
        void Shutdown();
    }

    /// <summary>
    /// 消息处理回调委托。
    /// </summary>
    /// <param name="msg">需要处理的消息内容。</param>
    /// <returns></returns>
    public delegate Acks MessageProcessCallback(MessageContent msg);

    /// <summary>
    /// 消息内容。
    /// </summary>
    public struct MessageContent
    {
        /// <summary>
        /// 消息所属的Topic。
        /// </summary>
        public string Topic { get; set; }

        /// <summary>
        /// 消息Topic的二级分类。
        /// </summary>
        public string TopicFlag { get; set; }

        /// <summary>
        /// 消息的唯一Key。
        /// </summary>
        public string MessageKey { get; set; }

        /// <summary>
        /// 消息唯一ID。
        /// </summary>
        public string MessageID { get; set; }

        /// <summary>
        /// 消息内容。
        /// </summary>
        public string MessageBody { get; set; }
    }

    /// <summary>
    /// 消息确认方式，是处理完成还是需要重新发送。
    /// </summary>
    public enum Acks
    {
        /// <summary>
        /// 消息已处理完成，可以丢弃。
        /// </summary>
        CommitMessage = 0,
        /// <summary>
        /// 消息处理失败，需要重新发送。
        /// </summary>
        ReconsumeLater = 1,
        /// <summary>
        /// 消息处理失败，需要重新分配到其它消费端处理。
        /// </summary>
        RejectLater = 2
    }
}
